<?php

namespace App\Http\Controllers\Api;

use App\Exceptions\BusinessException;
use App\Http\Resources\DocumentModelResource;
use App\Models\DocumentModel;
use App\Models\PraiseModel;
use App\Models\UserModel;
use App\Utils\ControllerModelTrait;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class DocumentController extends ApiController
{
    use ControllerModelTrait;

    /**
     * 获取发布列表
     * @param Request $request
     * @return JsonResponse
     */
    public function getList(Request $request): JsonResponse
    {
        $paginate = DocumentModel::where('uid', '>', 0)->orderByDesc('id')->paginate(20);
        $data = $this->injectUserAndPraiseIntoDocument($paginate->items());
        return $this->success($this->getPaginate($paginate, DocumentModelResource::collection($data)));
    }

    /**
     * 获取用户发布列表
     * @param Request $request
     * @return JsonResponse
     * @throws BusinessException
     */
    public function getUserList(Request $request): JsonResponse
    {
        $uid = $this->verifyInteger('uid');
        $paginate = DocumentModel::where('uid', $uid)->orderByDesc('id')->paginate(20);
        $data = $this->injectUserAndPraiseIntoDocument($paginate->items());
        return $this->success($this->getPaginate($paginate, DocumentModelResource::collection($data)));
    }

    /**
     * 新建发布
     * @param Request $request
     * @return JsonResponse
     */
    public function doSave(Request $request): JsonResponse
    {
        $covers = json_decode($request->input('cover_json', ''), true);
        $file = json_decode($request->input('file_json', ''), true);
        $poster = json_decode($request->input('poster_json', ''), true);
        $post = $request->only(['doc_type', 'title', 'uid', 'content']);
        $data = array_merge($post, [
            'covers'        => $covers ? json_encode(array_column($covers, 'path'), JSON_UNESCAPED_UNICODE) : null,
            'file'          => $file ? $file[0]['path']: '',
            'poster'        => $poster ? $poster[0]['path'] : ''
        ]);
        DocumentModel::create($data);
        return $this->success();
    }

    /**
     * 删除发布
     * @param Request $request
     * @return JsonResponse
     * @throws BusinessException
     */
    public function doDelete(Request $request): JsonResponse
    {
        $id = $this->verifyInteger('id');
        $Model = DocumentModel::where('id', $id);
        if ($request->input('uid'))
            $Model = $Model->where('uid', $request->input('uid', 0));
        $Model->delete();
        return $this->success();
    }

    /**
     * 点赞/取消点赞
     * @return JsonResponse
     * @throws BusinessException
     */
    public function praise(): JsonResponse
    {
        $uid = $this->verifyInteger('uid');
        $did = $this->verifyInteger('did');
        if ($praise = PraiseModel::where('did', $did)->where('uid', $uid)->first()) {
            $praise->delete();
            DocumentModel::where('id', $did)->decrement('praise_count');
        } else {
            PraiseModel::create(['uid' => $uid, 'did' => $did]);
            DocumentModel::where('id', $did)->increment('praise_count');
        }
        return $this->success();
    }

    /**
     * 向文档数据注入用户和点赞数据
     * @param $collection
     * @return array
     */
    private function injectUserAndPraiseIntoDocument($collection): array
    {
        if (!$collection instanceof Collection)
            $collection = new Collection($collection);
        $idArray = $collection->pluck('id')->toArray();
        $uidArray = $collection->pluck('uid')->toArray();
        $uid = \request()->input('uid', 0);
        $userPraiseData = $uid ? PraiseModel::whereIn('did', $idArray)->where('uid', $uid)->pluck('did')->toArray() : [];
        $userCollection = UserModel::whereIn('id', array_unique($uidArray))->get();
        $data = [];
        foreach ($collection as $item) {
            $item->user = $userCollection->where('id', $item->uid)->first();
            $item->praise_flag = in_array($item->id, $userPraiseData) ? 1 : 0;
            $data[] = $item;
        }
        return $data;
    }
}
